package com.ce.adapter;

import java.util.List;
import java.util.Map;

import com.ce.activity.R;
import com.ce.activity.SoftApplication;
import com.ce.utils.AsyncImageLoader;

import android.app.Activity;
import android.content.Context;
import android.graphics.drawable.Drawable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.Checkable;
import android.widget.ImageView;
import android.widget.TextView;

public class ListObjectAdapter extends BaseAdapter{
	
	protected List<? extends Map<String, ?>> mData;
	
	protected int[] mTo;
	
	protected String[] mFrom;
	
	private int mResource;
	
	private LayoutInflater mInflater;
	
	@SuppressWarnings("unused")
	private float mUserTextSize = 0;
	
	protected ViewBinder mViewBinder;
	
	protected AsyncImageLoader imageLoader;
	
	protected String mkdirs;
	
	protected Context context;
	
	protected View mView;
	
	protected int imageDef;

	public ListObjectAdapter(Activity activity, View v, List<? extends Map<String, ?>> data, int resource, String[] from, int[] to) {
		this(activity, "", v, data, resource, from, to);
	}
	
	public ListObjectAdapter(Activity activity, String dirs, View v, List<? extends Map<String, ?>> data, int resource, String[] from, int[] to) {
		this(activity, dirs, R.drawable.pic_dish_default, v, data, resource, from, to);
	}
	
	public ListObjectAdapter(Activity activity,String dirs, int imgDef, View v, List<? extends Map<String, ?>> data, int resource, String[] from, int[] to) {
		context = activity;
		mData = data;
		mResource = resource;
		mFrom = from;
		mTo = to;
		mkdirs = dirs;
		mView = v;
		imageDef = imgDef;
		imageLoader = ((SoftApplication)activity.getApplication()).getImageLoader();
		mInflater = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
	}
	
	public void setItemTextSize(float textSize) {
		mUserTextSize = textSize;
	}
	
	@Override
	public int getCount() {
		if(mData == null)
			return 0;
		return mData.size();
	}

	@Override
	public Object getItem(int position) {
		return mData.get(position);
	}

	@Override
	public long getItemId(int position) {
		return position;
	}

	@Override
	public View getView(int position, View convertView, ViewGroup parent) {
		return createViewFromResource(position, convertView, parent, mResource);
	}
	
	private View createViewFromResource(int position, View convertView, ViewGroup parent, int resource) {
		View v ;
		if(convertView == null)
			v = newView(resource, parent);
		else
			v = convertView;
		
		bindView(position, v);
		return v;
	}
	
	public View newView(int resource, ViewGroup parent) {
		View v = mInflater.inflate(resource, parent, false);
		int[] to = mTo;
		int count = to.length;
		View[] holder = new View[count];
		View iv = null;
		for(int i = 0; i < count; i++) {
			 iv = v.findViewById(to[i]);
			 iv.setVisibility(View.VISIBLE);
			holder[i] = iv;
		}
		v.setTag(holder);
		return v;
	}

	@SuppressWarnings("rawtypes")
	public void bindView(int position, View view) {
        final Map dataSet = (Map) mData.get(position);
        if (dataSet == null) {
            return;
        }

        final ViewBinder binder = mViewBinder;
        final String[] from = mFrom;
        final int[] to = mTo;
        final int count = to.length;

        for (int i = 0; i < count; i++) {
            final View v = view.findViewById(to[i]);
            if (v != null) {
                final Object data = dataSet.get(from[i]);
                String text = data == null ? "" : data.toString();
                if (text == null) {
                    text = "";
                }

                boolean bound = false;
                if (binder != null) {
                    bound = binder.setViewValue(v, data, text);
                }

                if (!bound) {
                    if (v instanceof Checkable) {
                        if (data instanceof Boolean) {
                            ((Checkable) v).setChecked((Boolean) data);
                        } else if (v instanceof TextView) {
                            setViewText((TextView) v, text);
                        } else {
                            throw new IllegalStateException(v.getClass().getName() +
                                    " should be bound to a Boolean, not a " +
                                    (data == null ? "<unknown type>" : data.getClass()));
                        }
                    } else if (v instanceof TextView) {
                        setViewText((TextView) v, text);
                    } else if (v instanceof ImageView) {
                        if (data instanceof Integer) {
                            setViewImage((ImageView) v, (Integer) data);                            
                        } else {
                        	v.setTag(text);
                            setViewImage((ImageView) v, text);
                        }
                    } else {
                        throw new IllegalStateException(v.getClass().getName() + " is not a " +
                                " view that can be bounds by this SimpleAdapter");
                    }
                }
            }
        }
    }
	
   public void setViewText(TextView v, String text) {
        v.setText(text);
    }
   
   public void setViewImage(ImageView v, int value) {
       v.setImageResource(value);
   }
   
	public void setViewImage(ImageView v, String value) {
		Drawable cacheImage = imageLoader.loadDrawable(context, mkdirs, value,
				new AsyncImageLoader.ImageCallback() {
					@Override
					public void imageLoaded(Drawable imageDrawable,
							String urlPath) {
						ImageView imgTag = (ImageView) mView.findViewWithTag(urlPath);
						if (imageDrawable != null && imgTag != null) {
							imgTag.setImageDrawable(imageDrawable);
						}
					}
				});
		if (cacheImage == null)
			v.setImageResource(imageDef);
		else
			v.setImageDrawable(cacheImage);
	}
   
   public ViewBinder getViewBinder() {
       return mViewBinder;
   }

   public void setViewBinder(ViewBinder viewBinder) {
       mViewBinder = viewBinder;
   }
   
   public static interface ViewBinder {
       boolean setViewValue(View view, Object data, String textRepresentation);
   }
}
